/**
 * @author erond
 */

package master;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import commonUtility.FtpClientThread;

/**
 * MasterDeleteClient_AfterLinkThread è la classe che genera thread in grado di implementare la parte di comunicazione
 * MASTER-SLAVE relativa all'invio allo slave del file 1_delete.txt e la ricezione di after_transfer_job.xml IN PARTICOLARE
 * COLLEGATA ALLA SOLA PARTE DI COMUNICAZIONE con l' After Gateway
 */
public class MasterDeleteClient_AfterLinkThread extends Thread {

	private Socket masterClientSocket = null;
	private InetAddress slaveIP = null;
	private int slaveDeleteServerPort_after = 0;

	public MasterDeleteClient_AfterLinkThread getMasterDeleteClient_AfterLinkThread() {
		return (MasterDeleteClient_AfterLinkThread) MasterDeleteClient_AfterLinkThread.currentThread();
	}

	public MasterDeleteClient_AfterLinkThread(InetAddress slaveIP, int slaveDeleteServerPort_after) {
		this.slaveIP=slaveIP;
		this.slaveDeleteServerPort_after=slaveDeleteServerPort_after;
	}	

	//metodo per lanciare il thread
	public void run() {

		DataInputStream inSock = null;
		DataOutputStream outSock = null;

		try {
			masterClientSocket=new Socket(slaveIP,slaveDeleteServerPort_after);
			System.out.println(Thread.currentThread().getName()+": creata la Socket di comunicazione con lo slave: "+masterClientSocket);
		} catch (UnknownHostException e) {	
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		try {
			// creazione stream di input e out da socket
			inSock = new DataInputStream(masterClientSocket.getInputStream());
			outSock = new DataOutputStream(masterClientSocket.getOutputStream());
		}
		catch (IOException ioe) {
			System.out
			.println("MasterDeleteClient_AfterLinkThread: Problemi nella creazione degli stream di input/output "
					+ "su socket: ");
			ioe.printStackTrace();
			// il server continua l'esecuzione riprendendo dall'inizio del ciclo
			return;
		}
		
		/**
		 * Ho ricevuto un'accettazione di connessione da parte dello SLAVE.
		 * Posso aprire il canale, e
		 * 1) inviare il file after_wants_thief.txt (lista di elementi MACADDRESS)
		 * 2) bloccarmi in attesa di ricevere dallo SLAVE il file send_after_transfer_job.xml
		 *    contenente le chiavi <MAC><FILE><TRANSMITTEDTIME><PORT>
		 */

		try {    

			/**
			 * 1) trasferimento del file after_wants_thief.txt
			 */
			
			System.out.println("MasterDeleteClient_AfterLinkThread: invio after_wants_thief.txt allo Slave.");

			FtpClientThread after_wants_thief = new FtpClientThread(slaveIP, 2122, "./gatewayTmp/after_wants_thief.txt", "1_delete.txt");
			after_wants_thief.setName("MasterDeleteClient_GatewayServer_after_wants_thiefFtpClientThread");
			after_wants_thief.start();

			//Attendo che il trasferimento sia completato
			try {
				after_wants_thief.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			/**
			 * devo inviare allo slave AFTERWANTSTHIEFREADY per notificargli l'avvenuto trasferimento
			 */

			String signal = null;

			while(true) {
				try {
					outSock.writeUTF("AFTERWANTSTHIEFREADY");
					while(inSock.available()>=0) {
						signal=inSock.readUTF();
						if(signal.equalsIgnoreCase("AFTERWANTSTHIEFREADYRECEIVED")) {
							System.err.println(Thread.currentThread().getName()+": Ricevuto "+signal+" ..continuo!");
							/**
							 * se ricevo questa stringa vuol dire che lo slave ha ricevuto AFTERWANTSTHIEFREADY
							 */
							break;
						}
					}
					break;
				} catch (IOException e) {
					e.printStackTrace();
					System.exit(1);
				}
			}

			try {
				outSock.flush();
			} catch (IOException ioe) {
				System.err.println(Thread.currentThread().getName()+": Eccezione nella flush");
				ioe.printStackTrace();
			}


			/**
			 * 2) Attesa del file send_after_transfer_job.xml. Invio OK se trasferito correttamente
			 */

			System.out.println("MasterDeleteClient_BeforeLinkThread: ricevo send_after_transfer_job.xml dallo slaveDeleteServer_MasterConnector_after");

			try {
				while(inSock.available()>=0) {
					signal=inSock.readUTF();
					if(signal.equalsIgnoreCase("TRANSFERJOBONEREADY")) {
						System.err.println(Thread.currentThread().getName()+": Ricevuto "+signal+" ..continuo!");
						/**
						 * se ricevo questa stringa vuol dire che lo slave ha inviato al mio ftp server
						 * il file 0_transfer_job.xml salvandolo come send_before_transfer_job.xml.
						 * CONTROLLO DI SICUREZZA: invio al vicino la stringa TRANSFERJOBONEREADYRECEIVED
						 */
						outSock.writeUTF("TRANSFERJOBONEREADYRECEIVED");
						break;
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
				System.exit(1);
			}

	
			try {
				outSock.flush();
			} catch (IOException ioe) {
				System.err.println(Thread.currentThread().getName()+": Eccezione nella flush");
				ioe.printStackTrace();
			}

		} catch (Exception e) {
			/**
			 * Chiusura socket ed I/O stream
			 */
			System.err.println("MasterDeleteClient_AfterLinkThread: Errore nella chiusura dei canali...\n");
			e.printStackTrace();
			try {
				inSock.close();
				outSock.close();
				masterClientSocket.close();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			System.out.println("MasterDeleteClient_AfterLinkThread: Chiudo i canali I/O e la socket\n");
		}

		System.err.println("MasterDeleteClient_AfterLinkThread: Chiudo i canali I/O e la socket. Termino.\n");

		try {
			inSock.close();
			outSock.close();
			masterClientSocket.close();
		} catch (Exception e1) {
			e1.printStackTrace();
		}

	}//fine run()

}//fine MasterDeleteClient_AfterLinkThread 